package cn.shengchao.examstar.product.ohs.remote.rpc;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.shengchao.examstar.product.acl.ports.repositories.IProductCourseSettingRepository;
import cn.shengchao.examstar.product.acl.ports.repositories.IProductRepository;
import cn.shengchao.examstar.product.domain.entity.Course;
import cn.shengchao.examstar.product.domain.valobj.ProductName;
import cn.shengchao.examstar.product.event.ProductCourseSettingGKBatchSaveEvent;
import cn.shengchao.examstar.product.infrastructure.dao.po.TProductCourseNodes;
import cn.shengchao.examstar.rpc.base.PageResult;
import cn.shengchao.examstar.rpc.base.TransResult;
import cn.shengchao.examstar.rpc.product.api.IProductCourseSettingRpc;
import cn.shengchao.examstar.rpc.product.base.CourseStructType;
import cn.shengchao.examstar.rpc.product.req.*;
import cn.shengchao.examstar.rpc.product.res.ProductCourseSettingHasListVo;
import cn.shengchao.examstar.rpc.product.res.ProductCourseSettingVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.redis.core.RedisTemplate;
import top.continew.starter.extension.crud.model.entity.BaseIdDO;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @program: examstarapi
 * @description: 产品合作有效期配置
 * @author: Xiong weiqiang
 * @create: 2025-06-30 18:25
 */
@DubboService
public class ProductCourseSettingRpc implements IProductCourseSettingRpc {
    @Autowired
    private IProductCourseSettingRepository productCourseSettingRepository;
    @Autowired
    private IProductRepository productRepository;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;
    @Override
    public PageResult<ProductCourseSettingVo> queryProductCourseSetting(ProductCourseSettingPageQuery query) {
        try(Page<Object> page= PageHelper.startPage(query.getPage(), query.getSize())){
            List<ProductCourseSettingVo> list=productCourseSettingRepository.pageList(query);
            List<Long> productIds=list.stream().map(ProductCourseSettingVo::getProductId).toList();
            List<TProductCourseNodes> productCourseNodes=productRepository.findCourseNodesByProductIds(productIds,true);
            if (CollUtil.isNotEmpty(productCourseNodes)){
                List<Long> courseIds=productCourseNodes.stream().map(TProductCourseNodes::getCourseId).toList();
                List<Course> courseList=productRepository.findCourseByIds(courseIds);
                Map<Long,TProductCourseNodes> productMap=productCourseNodes.stream().collect(Collectors.toMap(BaseIdDO::getId, Function.identity()));
                Map<Long, ProductName> courseNameMap=courseList.stream().collect(Collectors.toMap(Course::getId, Course::getName));

                list.forEach(productCourseSettingVo ->{
                    TProductCourseNodes tProductCourseNode=productMap.get(productCourseSettingVo.getProductId());
                    productCourseSettingVo.setProductName(tProductCourseNode.getName());
                    productCourseSettingVo.setCourseName(courseNameMap.containsKey(tProductCourseNode.getCourseId())?courseNameMap.get(tProductCourseNode.getCourseId()).getValue():"缺失");
                    productCourseSettingVo.setCourseId(tProductCourseNode.getCourseId());
                });
            }
            return PageResult.of(page.getTotal(), list);
        }
    }
    @Override
    public TransResult<String> saveProductCourseSettingByCourse(ProductCourseSettingBatchSaveDto productCourseSettingBatchSaveDto){
        Long batchId=System.currentTimeMillis();
        productCourseSettingBatchSaveDto.setBatchId(batchId);
        productCourseSettingRepository.saveProductCourseSettingByCourse(productCourseSettingBatchSaveDto);
        return TransResult.success("保存成功");
    }
    @Override
    public TransResult<String> saveProductCourseSettingForGkCourse(ProductCourseSettingBatchSaveDto productCourseSettingBatchSaveDto){
        String lockKey="PRODUCT_COURSE_GK_BATCH_INSERT";
        Long batchId=System.currentTimeMillis();
        if (!redisTemplate.hasKey(lockKey)) {
            productCourseSettingBatchSaveDto.setBatchId(batchId);
            applicationEventPublisher.publishEvent(new ProductCourseSettingGKBatchSaveEvent(productCourseSettingBatchSaveDto));
            productCourseSettingRepository.saveProductCourseSettingForGkCourse(productCourseSettingBatchSaveDto);
        }else {
            return TransResult.fail("赶考课程数据量大，请不要重复操作");
        }
        return TransResult.success("赶考课程数据量大，请耐心等待");
    }

    @Override
    public TransResult<String> saveProductCourseSetting(ProductCourseSettingDto productCourseSettingDto) {
        return productCourseSettingRepository.saveProductCourseSetting(productCourseSettingDto);
    }

    @Override
    public TransResult<String> deleteProductCourseSetting(ProductCourseSettingDeleteDto productCourseSettingDeleteDto) {
        return productCourseSettingRepository.deleteProductCourseSetting(productCourseSettingDeleteDto);
    }

    @Override
    public ProductCourseSettingHasListVo queryProductCourseSettingForShow(ProductCourseSettingQuery query) {
        if (CourseStructType.COURSE.name().equals(query.getStructType())){
            List<ProductCourseSettingVo> list=productCourseSettingRepository.queryForCourse(query.getProductId());
            return mergeProductCourseSettingForShow(query.getProductId(),list);
        }else if (CourseStructType.LESSON.name().equals(query.getStructType())){
            List<Long> sectionIds=productRepository.findCourseNodesByParentLessonId(query.getProductId());
            List<ProductCourseSettingVo> list=productCourseSettingRepository.queryForLesson(query.getProductId(),sectionIds);
            return mergeProductCourseSettingForShow(query.getProductId(),list);
        }else if (CourseStructType.SECTION.name().equals(query.getStructType())){
            List<ProductCourseSettingVo> list=productCourseSettingRepository.queryForSection(query.getProductId());
            ProductCourseSettingHasListVo productCourseSettingHasListVo= mergeProductCourseSettingForShow(query.getProductId(),list);
            if (CollUtil.isNotEmpty( list)) {
                boolean isIn = false;
                for (ProductCourseSettingVo productCourseSettingVo : list) {
                    //判断当前时间是否在合作时间段内
                    if (DateUtil.isIn(new Date(), productCourseSettingVo.getCorpStartTime(), productCourseSettingVo.getCorpEndTime())) {
                        productCourseSettingHasListVo.setId(productCourseSettingVo.getId());
                        productCourseSettingHasListVo.setCorpStartTime(productCourseSettingVo.getCorpStartTime());
                        productCourseSettingHasListVo.setCorpEndTime(productCourseSettingVo.getCorpEndTime());
                        productCourseSettingHasListVo.setUnitPayDay(productCourseSettingVo.getUnitPayDay());
                        isIn = true;
                    }
                }
                if (!isIn) {
                    productCourseSettingHasListVo.setId(list.getFirst().getId());
                    productCourseSettingHasListVo.setCorpStartTime(list.getFirst().getCorpStartTime());
                    productCourseSettingHasListVo.setCorpEndTime(list.getFirst().getCorpEndTime());
                    productCourseSettingHasListVo.setUnitPayDay(list.getFirst().getUnitPayDay());
                }
            }
            productCourseSettingHasListVo.setOtherList(list);
            return productCourseSettingHasListVo;
        }else{
            return mergeProductCourseSettingForShow(query.getProductId(),null);
        }
    }

    private ProductCourseSettingHasListVo mergeProductCourseSettingForShow(Long productId,List<ProductCourseSettingVo> list) {
        ProductCourseSettingHasListVo productCourseSettingHasListVo=new ProductCourseSettingHasListVo();
        productCourseSettingHasListVo.setProductId(productId);
        if (CollUtil.isEmpty(list)){
            productCourseSettingHasListVo.setLessonCount(0);
            return productCourseSettingHasListVo;
        }
        List<Long> productIds=list.stream().map(ProductCourseSettingVo::getProductId).distinct().toList();
        productCourseSettingHasListVo.setLessonCount(productIds.size());
        Date beginDate=null;
        Date endDate=null;
        for (ProductCourseSettingVo productCourseSettingVo:list){
            if (beginDate==null||(productCourseSettingVo.getCorpStartTime()!=null&&productCourseSettingVo.getCorpStartTime().before(beginDate))){
                beginDate=productCourseSettingVo.getCorpStartTime();
            }
            if (endDate==null||(productCourseSettingVo.getCorpEndTime()!=null&&productCourseSettingVo.getCorpEndTime().after(endDate))){
                endDate=productCourseSettingVo.getCorpEndTime();
            }
        }
        productCourseSettingHasListVo.setCorpStartTime(beginDate);
        productCourseSettingHasListVo.setCorpEndTime(endDate);
        return productCourseSettingHasListVo;
    }
}